﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using OpenAuth.App.Interface;
using OpenAuth.App.Request;
using OpenAuth.App.Response;
using OpenAuth.Repository.Domain;
using OpenAuth.Repository.Interface;


namespace OpenAuth.App
{
    public class InspectPlanApp : BaseApp<InspectPlan>
    {
        private RevelanceManagerApp _revelanceApp;
        private IAuth _auth;
        private ILogger<InspectPlanApp> _logger;
        private IHostingEnvironment _hostingEnvironment;

        /// <summary>
        /// 加载列表
        /// </summary>
        public TableData Load(QueryInspectPlanListReq request)
        {
            var loginContext = _auth.GetCurrentUser();
            if (loginContext == null)
            {
                throw new CommonException("登录已过期", Define.INVALID_TOKEN);
            }

            var properties = loginContext.GetProperties("InspectPlan");

            if (properties == null || properties.Count == 0)
            {
                throw new Exception("当前登录用户没有访问该模块字段的权限，请联系管理员配置");
            }

            List<string> orgIdList = new List<string>();
            if (!string.IsNullOrEmpty(request.orgId))
            {
                var org = loginContext.Orgs.SingleOrDefault(u => u.Id == request.orgId);
                foreach (Org item in loginContext.Orgs)
                {
                    if (item.CascadeId.Contains(org.CascadeId))
                    {
                        orgIdList.Add(item.Id);
                    }
                }
            }
            else
            {
                orgIdList = loginContext.Orgs.Select(u => u.Id).ToList();
            }

            var result = new TableData();
            var objs = UnitWork.Find<InspectPlan>(u => orgIdList.Contains(u.OrgId));
            if (!string.IsNullOrEmpty(request.key))
            {
                objs = objs.Where(u => u.Name.Contains(request.key) || u.Id.Contains(request.key));
            }


            var propertyStr = string.Join(',', properties.Select(u => u.Key));
            result.columnHeaders = properties;
            result.data = objs.OrderByDescending(u => u.CreateTime)
                .Skip((request.page - 1) * request.limit)
                .Take(request.limit).Select($"new ({propertyStr})");
            result.count = objs.Count();
            return result;
        }

        public void Add(InspectPlan obj)
        {
            obj.CreateTime = DateTime.Now;
            Repository.Add(obj);
        }

        public void Update(InspectPlan obj)
        {
            var oldPlan = UnitWork.FindSingle<InspectPlan>(u => u.Id == obj.Id);
            if (obj.Cycle != oldPlan.Cycle || obj.Number != oldPlan.Number || obj.SerialDay != oldPlan.SerialDay)
            {
                UnitWork.ExecuteSql($"delete from InspectShift where InspectPlanId='{obj.Id}'");
                UnitWork.ExecuteSql($"delete from InspectSchedule where InspectPlanId='{obj.Id}' and StartTime>'{DateTime.Now}'");
            }
            UnitWork.Delete<InspectPlanContent>(u => u.InspectPlanId == obj.Id);

            UnitWork.Update<InspectPlan>(u => u.Id == obj.Id, u => new InspectPlan
            {
                Name = obj.Name,
                OrgId = obj.OrgId,
                PartId = obj.PartId,
                Cycle = obj.Cycle,
                Number = obj.Number,
                Status = obj.Status,
                SerialDay = obj.SerialDay
            });
            foreach (var item in obj.Contents)
            {
                item.InspectPlanId = obj.Id;
                UnitWork.Add(item);
            }
            UnitWork.Save();
        }

        public void Delete(string[] ids)
        {
            UnitWork.Delete<InspectPlan>(u => ids.Contains(u.Id));
            UnitWork.Delete<InspectPlanContent>(u => ids.Contains(u.InspectPlanId));
            UnitWork.Delete<InspectShift>(u => ids.Contains(u.InspectPlanId));
            UnitWork.Delete<InspectPlanTeam>(u => ids.Contains(u.InspectPlanId));
            UnitWork.Delete<InspectPlanTeamTime>(u => ids.Contains(u.InspectPlanId));
            foreach (var id in ids)
            {
                UnitWork.ExecuteSql($"delete InspectSchedule where InspectPlanId ='{id}'");
            }
            UnitWork.Save();
        }

        public InspectPlan GetOne(String id)
        {
            return UnitWork.Find<InspectPlan>(u => u.Id == id).Include(u => u.Contents).FirstOrDefault();
        }

        public InspectContentList GetContentItemsById(string orgId)
        {
            InspectContentList result = new InspectContentList();
            if (string.IsNullOrEmpty(orgId))
                return result;
            var orgs = UnitWork.Find<Org>(null);
            var org = UnitWork.FindSingle<Org>(u => u.Id == orgId);
            string cascadeId = org.CascadeId;
            List<string> orgIdList = new List<string>() { "" };
            foreach (Org item in orgs)
            {
                if (item.CascadeId.Contains(cascadeId))
                {
                    orgIdList.Add(item.Id);
                }
            }
            result.InspectAreas = UnitWork.Find<InspectArea>(u => orgIdList.Contains(u.OrgId)).ToList();
            result.InspectStandards = UnitWork.Find<InspectStandard>(u => orgIdList.Contains(u.OrgId)).ToList();
            result.EquipmentInventories = UnitWork.Find<EquipmentInventory>(u => orgIdList.Contains(u.OrgId)).ToList();

            return result;
        }

        public void ChangeStatus(InspectPlan inspectPlan)
        {
            UnitWork.Update<InspectPlan>(u => u.Id == inspectPlan.Id, u => new InspectPlan
            {
                Status = inspectPlan.Status
            });
        }

        /// <summary>
        /// 排班增加或修改
        /// </summary>
        public void ShiftAddOrUpdate(List<InspectShift> inspectShifts, string type)
        {

            foreach (InspectShift inspectShift in inspectShifts)
            {
                if (type == "Insert")
                {
                    UnitWork.Add(inspectShift);
                }
                else
                {
                    UnitWork.Update<InspectShift>(u => u.Id == inspectShift.Id, u => new InspectShift
                    {
                        Personnel = inspectShift.Personnel,
                        Sort = inspectShift.Sort,
                        StartTime = inspectShift.StartTime,
                        EndTime = inspectShift.EndTime,
                        IncludeSaturday = inspectShift.IncludeSaturday,
                        IncludeSunday = inspectShift.IncludeSunday
                    });
                }
            }
            UnitWork.Save();
        }

        public List<User> GetInspectPersons(string partId, string search)
        {
            List<User> userList = new List<User>();
            List<string> userIdList = UnitWork.Find<Relevance>(u => u.Key == "UserRole" && u.SecondId == partId)
                .Select(u => u.FirstId)
                .ToList();
            userList = UnitWork.Find<User>(u => userIdList.Contains(u.Id) && u.Name.Contains(search)).ToList();
            return userList;
        }

        public List<InspectShift> GetInspectShifts(string id)
        {
            return UnitWork.Find<InspectShift>(u => u.InspectPlanId == id).OrderBy(u => u.Sort).ToList();
        }

        public List<User> GetUsers(string userIds)
        {
            var ids = userIds.Split(",");
            return UnitWork.Find<User>(u => ids.Contains(u.Id)).ToList();
        }

        /// <summary>
        /// 计划排班
        /// </summary>
        public void Scheduling(string planId, DateTime startDate, DateTime endDate)
        {
            var plan = UnitWork.Find<InspectPlan>(u => u.Id == planId).First();
            if (plan.Cycle == 5) //轮班模式
            {
                var teams = UnitWork.Find<InspectPlanTeam>(u => u.InspectPlanId == planId).OrderBy(u => u.Sort).ToList();
                if (!teams.Any()) throw new Exception("请先进行排班设置");
                var currentUser = _auth.GetCurrentUser().User;
                var times = UnitWork.Find<InspectPlanTeamTime>(u => u.InspectPlanId == planId).OrderBy(u => u.Sort).ToList();
                //判断是否排版过，排班过的从后面接下去轮班
                List<string> shiftList = new List<string>();
                var startMin = times.First().TimeSpan.Split('-')[0];
                if (plan.ShiftNew != 1)
                {
                    var schedules = UnitWork
                        .Find<InspectSchedule>(u => u.InspectPlanId == planId &&
                            u.StartTime < startDate.ToString($"yyyy-MM-dd {startMin}").ToDateTime())
                        .OrderByDescending(u => u.StartTime).ToList();
                    if (schedules.Count > 0)
                    {
                        foreach (var schedule in schedules)
                        {
                            if (shiftList.Count < times.Count)
                            {
                                if (!shiftList.Contains(schedule.ShiftTeam))
                                    shiftList.Add(schedule.ShiftTeam);
                            }
                            else break;
                        }
                    }
                }
                startDate = startDate.ToString($"yyyy-MM-dd {startMin}").ToDateTime();
                int index = 0;
                if (shiftList.Count != 0 && shiftList.Count == times.Count)
                {
                    shiftList.Reverse();
                    foreach (var team in teams)
                    {
                        bool flag = true;
                        for (int i = 0; i < shiftList.Count; i++)
                        {
                            switch (i)
                            {
                                case 0:
                                    if (team.Team1 != shiftList[i])
                                        flag = false;
                                    break;
                                case 1:
                                    if (team.Team2 != shiftList[i])
                                        flag = false;
                                    break;
                                case 2:
                                    if (team.Team3 != shiftList[i])
                                        flag = false;
                                    break;
                                case 3:
                                    if (team.Team4 != shiftList[i])
                                        flag = false;
                                    break;
                                case 4:
                                    if (team.Team5 != shiftList[i])
                                        flag = false;
                                    break;
                                case 5:
                                    if (team.Team6 != shiftList[i])
                                        flag = false;
                                    break;
                                case 6:
                                    if (team.Team7 != shiftList[i])
                                        flag = false;
                                    break;
                                case 7:
                                    if (team.Team8 != shiftList[i])
                                        flag = false;
                                    break;
                                case 8:
                                    if (team.Team9 != shiftList[i])
                                        flag = false;
                                    break;
                                case 9:
                                    if (team.Team10 != shiftList[i])
                                        flag = false;
                                    break;
                            }
                        }

                        if (flag)
                        {
                            index = team.Sort + 1;
                        }
                    }
                }
                DateTime nowTime = DateTime.Now;
                DateTime flagTime = startDate;
                int loopIndex = 0;
                DateTime maxTime = new DateTime(2000, 1, 1);
                var planTeams = UnitWork.Find<InspectItem>(null).ToList();
                UnitWork.Delete<InspectSchedule>(u => u.InspectPlanId == planId && u.StartTime >= startDate);
                while (flagTime <= endDate)
                {
                    bool addOneDay = true;
                    foreach (var shiftTeam in teams)
                    {
                        if (loopIndex < index)
                        {
                            loopIndex++;
                            continue;
                        }

                        bool hasAdd = true;
                        for (int m = 1; m <= plan.SerialDay; m++)
                        {
                            for (int i = 1; i <= times.Count; i++)
                            {
                                hasAdd = true;
                                var shiftTime = times[i - 1];
                                string[] timeArr = shiftTime.TimeSpan.Split('-');
                                var tempTime1 = nowTime.ToString($"yyyy-MM-dd {timeArr[1]}").ToDateTime();
                                var tempTime2 = nowTime.ToString($"yyyy-MM-dd {timeArr[0]}").ToDateTime();
                                if (tempTime1 <= tempTime2)
                                {
                                    tempTime1 = tempTime1.AddDays(1);
                                }
                                var subTract = tempTime1.Subtract(tempTime2);
                                var spanMin = Math.Floor(subTract.TotalMinutes / plan.Number);
                                string teamName = "", teamId = "";
                                switch (i)
                                {
                                    case 1:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team1)?.Name;
                                        teamId = shiftTeam.Team1;
                                        break;
                                    case 2:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team2)?.Name;
                                        teamId = shiftTeam.Team2;
                                        break;
                                    case 3:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team3)?.Name;
                                        teamId = shiftTeam.Team3;
                                        break;
                                    case 4:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team4)?.Name;
                                        teamId = shiftTeam.Team4;
                                        break;
                                    case 5:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team5)?.Name;
                                        teamId = shiftTeam.Team5;
                                        break;
                                    case 6:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team6)?.Name;
                                        teamId = shiftTeam.Team6;
                                        break;
                                    case 7:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team7)?.Name;
                                        teamId = shiftTeam.Team7;
                                        break;
                                    case 8:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team8)?.Name;
                                        teamId = shiftTeam.Team8;
                                        break;
                                    case 9:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team9)?.Name;
                                        teamId = shiftTeam.Team9;
                                        break;
                                    case 10:
                                        teamName = planTeams.FirstOrDefault(u => u.Id == shiftTeam.Team10)?.Name;
                                        teamId = shiftTeam.Team10;
                                        break;
                                }
                                for (int j = 1; j <= plan.Number; j++)
                                {
                                    var sTime = flagTime.ToString($"yyyy-MM-dd {timeArr[0]}").ToDateTime().AddMinutes(spanMin * (j - 1));
                                    var eTime = flagTime.ToString($"yyyy-MM-dd {timeArr[0]}").ToDateTime().AddMinutes(spanMin * j);
                                    if (j == plan.Number)
                                        eTime = eTime.ToString($"yyyy-MM-dd {timeArr[1]}").ToDateTime();
                                    if (eTime <= sTime)
                                        eTime = eTime.AddDays(1);
                                    maxTime = eTime;

                                    UnitWork.Add(new InspectSchedule()
                                    {
                                        InspectPlanId = planId,
                                        ClassName = $"{teamName}({j})班",
                                        ShiftTeam = teamId,
                                        StartTime = sTime,
                                        EndTime = eTime,
                                        IsInspection = false,
                                        IsViolation = false,
                                        CreateId = currentUser.Id,
                                        CreateTime = nowTime
                                    });
                                }

                                if (flagTime.ToString("yyyy-MM-dd") != maxTime.ToString("yyy-MM-dd"))
                                {
                                    flagTime = flagTime.AddDays(1);
                                    addOneDay = false;
                                    hasAdd = false;
                                }
                            }
                            if (hasAdd)
                                flagTime = flagTime.AddDays(1);
                        }
                        if (!hasAdd && addOneDay)
                            flagTime = flagTime.AddDays(1);
                    }
                }
                UnitWork.Update<InspectPlan>(u => u.Id == planId, u => new InspectPlan() { ShiftNew = 0 });
            }
            else//常规排班
            {
                var shifts = UnitWork.Find<InspectShift>(u => u.InspectPlanId == planId).OrderBy(u => u.Sort);
                if (!shifts.Any())
                    throw new Exception("请先进行排班设置");
                var shiftFirst = shifts.First();
                if (shiftFirst.Cycle == 4)
                    UnitWork.Delete<InspectSchedule>(u => u.InspectPlanId == planId);
                else
                    UnitWork.Delete<InspectSchedule>(u => u.InspectPlanId == planId && u.StartTime >= startDate);
                var currentUser = _auth.GetCurrentUser().User;
                var nowTime = DateTime.Now;
                DateTime flagTime = startDate;
                switch (shiftFirst.Cycle)
                {
                    case 1: //按天巡检
                        while (flagTime <= endDate)
                        {
                            foreach (var item in shifts)
                            {
                                DateTime planStart = Convert.ToDateTime(flagTime.ToString($"yyyy-MM-dd {item.StartTime}"));
                                if (planStart < nowTime)
                                    continue;
                                DateTime planEnd = Convert.ToDateTime(flagTime.ToString($"yyyy-MM-dd {item.EndTime}"));
                                if (planEnd <= planStart)
                                {
                                    planEnd = planEnd.AddDays(1);
                                    //lagTime = flagTime.AddDays(1);
                                }
                                if (!item.IncludeSaturday)
                                {
                                    if ((int)planStart.DayOfWeek == 6)
                                        continue;
                                }
                                if (!item.IncludeSunday)
                                {
                                    if ((int)planStart.DayOfWeek == 0)
                                        continue;
                                }
                                UnitWork.Add(new InspectSchedule
                                {
                                    InspectPlanId = planId,
                                    ClassName = $"第{item.Sort + 1}班（{planStart:yyyy-MM-dd HH:mm}至{planEnd:yyyy-MM-dd HH:mm}）",
                                    Executor = item.Personnel,
                                    StartTime = planStart,
                                    EndTime = planEnd,
                                    IsInspection = false,
                                    IsViolation = false,
                                    CreateId = currentUser.Id,
                                    CreateTime = nowTime
                                });
                            }
                            flagTime = flagTime.AddDays(1);
                        }
                        break;
                    case 2: //按周巡检
                        while (flagTime <= endDate)
                        {
                            foreach (var item in shifts)
                            {
                                if (((int)flagTime.DayOfWeek).ToString() != item.EndTime) continue;
                                string endWeek = item.EndTime == "0" ? "7" : item.EndTime;
                                DateTime planStart =
                                    flagTime.AddDays(-(Convert.ToInt32(endWeek) - Convert.ToInt32(item.StartTime)));
                                if (planStart < nowTime)
                                    continue;
                                DateTime planEnd = Convert.ToDateTime(flagTime.ToString($"yyyy-MM-dd 23:59:59"));
                                UnitWork.Add(new InspectSchedule
                                {
                                    InspectPlanId = planId,
                                    ClassName = $"第{item.Sort + 1}班（{planStart:yyyy-MM-dd}至{planEnd:yyyy-MM-dd}）",
                                    Executor = item.Personnel,
                                    StartTime = planStart,
                                    EndTime = planEnd,
                                    IsInspection = false,
                                    IsViolation = false,
                                    CreateId = currentUser.Id,
                                    CreateTime = nowTime
                                });
                            }
                            flagTime = flagTime.AddDays(1);
                        }
                        break;
                    case 3: //按月巡检
                        for (var year = startDate.Year; year <= endDate.Year; year++)
                        {
                            for (var month = 1; month <= 12; month++)
                            {
                                foreach (var item in shifts)
                                {
                                    string startTimeStr = DateTimeUtil.FormatDate(Convert.ToInt32(year), month, Convert.ToInt32(item.StartTime));
                                    string endTimeStr = DateTimeUtil.FormatDate(Convert.ToInt32(year), month, Convert.ToInt32(item.EndTime));
                                    DateTime startTime = Convert.ToDateTime(startTimeStr);
                                    DateTime endTime = Convert.ToDateTime(endTimeStr).AddDays(1).AddSeconds(-1);
                                    if (startTime < DateTime.Now || startTime > endTime || startTime < startDate)
                                        continue;
                                    UnitWork.Add(new InspectSchedule
                                    {
                                        InspectPlanId = planId,
                                        ClassName = $"第{item.Sort + 1}班（{startTime:yyyy-MM-dd}至{endTime:yyyy-MM-dd}）",
                                        Executor = item.Personnel,
                                        StartTime = startTime,
                                        EndTime = endTime,
                                        IsInspection = false,
                                        IsViolation = false,
                                        CreateId = currentUser.Id,
                                        CreateTime = nowTime
                                    });
                                }
                            }
                        }
                        break;
                    case 4: //按年巡检
                        for (var year = startDate.Year; year <= endDate.Year; year++)
                        {
                            foreach (var item in shifts)
                            {
                                DateTime startTime = Convert.ToDateTime(year + "-" + item.StartTime);
                                DateTime endTime = Convert.ToDateTime(year + "-" + item.EndTime).AddDays(1).AddSeconds(-1);
                                if (startTime >= endTime || endTime < DateTime.Now)
                                    continue;
                                UnitWork.Add(new InspectSchedule
                                {
                                    InspectPlanId = planId,
                                    ClassName = $"第{item.Sort + 1}班（{startTime:yyyy-MM-dd}至{endTime:yyyy-MM-dd}）",
                                    Executor = item.Personnel,
                                    StartTime = startTime,
                                    EndTime = endTime,
                                    IsInspection = false,
                                    IsViolation = false,
                                    CreateId = currentUser.Id,
                                    CreateTime = nowTime
                                });
                            }
                        }
                        break;
                }
            }

            UnitWork.Save();
        }

        public List<ScheduleList> GetScheduList(string planId)
        {
            List<ScheduleList> result = new List<ScheduleList>();
            var list = UnitWork.Find<InspectSchedule>(u => u.InspectPlanId == planId && u.EndTime > DateTime.Now)
                .OrderBy(u => u.StartTime).Take(50).ToList();
            if (!list.Any())
                return result;
            var plan = UnitWork.FindSingle<InspectPlan>(u => u.Id == planId);
            int cycle = plan.Cycle;
            if (cycle == 5)
            {
                var planTeam = UnitWork.Find<InspectItem>(null).ToList();
                var a = from p in list
                        select new ScheduleList
                        {
                            ClassName = p.ClassName,
                            StartTime = p.StartTime.ToString("yyyy-MM-dd HH:mm"),
                            EndTime = p.EndTime.ToString("yyyy-MM-dd HH:mm"),
                            Executor = planTeam.FirstOrDefault(u => u.Id == p.ShiftTeam) == null ? ""
                                : planTeam.First(u => u.Id == p.ShiftTeam).Name
                        };
                result = a.ToList();
            }
            else
            {
                var schedule = list.FirstOrDefault();
                string[] executor = string.IsNullOrEmpty(schedule.Executor) ? null : schedule.Executor.Split(",");
                var users = UnitWork.Find<User>(u => executor.Contains(u.Id)).Select(u => u.Name).ToList();
                var a = from p in list
                        select new ScheduleList
                        {
                            ClassName = p.ClassName,
                            StartTime = plan.Cycle == 1 ? p.StartTime.ToString("yyyy-MM-dd HH:mm") : p.StartTime.ToShortDateString(),
                            EndTime = plan.Cycle == 1 ? p.EndTime.ToString("yyyy-MM-dd HH:mm") : p.EndTime.ToShortDateString(),
                            Executor = string.Join(",", users)
                        };
                result = a.ToList();
            }

            return result;
        }

        public List<InspectPlan> GetPlanForName(string name)
        {
            return UnitWork.Find<InspectPlan>(u => u.Name.Contains(name)).ToList();
        }

        public void UploadShiftExcel(IFormFile excelfile, string planId)
        {
            if (excelfile != null)
            {
                _logger.LogInformation("收到新文件: " + excelfile.FileName);
                _logger.LogInformation("收到新文件: " + excelfile.Length);
            }
            else
            {
                _logger.LogWarning("收到新文件为空");
            }
            string serverPath;
            using (var binaryReader = new BinaryReader(excelfile.OpenReadStream()))
            {
                var fileName = Path.GetFileName(excelfile.FileName);
                var data = binaryReader.ReadBytes((int)excelfile.Length);
                //判断文件是否为空
                if (string.IsNullOrEmpty(fileName))
                {
                    throw new Exception("文件名不能为空");
                }

                //判断文件是否为空
                if (data.Length < 1)
                {
                    throw new Exception("文件不能为空");
                }
                var appSetting = new AppSetting();
                var filePath = appSetting.UploadPath;
                if (string.IsNullOrEmpty(filePath))
                {
                    filePath = AppContext.BaseDirectory;
                }

                var uploadPath = filePath + "/" + "轮班模板/";
                _logger.LogInformation("文件写入：" + uploadPath);
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }

                var ext = Path.GetExtension(fileName).ToLower();
                string newName = GenerateId.GenerateOrderNumber() + ext;
                serverPath = uploadPath + newName;
                using (var fs = new FileStream(serverPath, FileMode.Create))
                {
                    fs.Write(data, 0, data.Length);
                    fs.Close();
                }
            }
            var file = new FileInfo(serverPath);
            var sourceDataSet = OfficeHelper.InputEPPlusByExcelToDS(file);
            var shiftTable = sourceDataSet.Tables["班组轮班表"];
            var timeTable = sourceDataSet.Tables["班次时间表"];
            if (shiftTable.Rows.Count == 0)
                throw new Exception("班组轮班表不能为空");

            if (timeTable.Rows.Count == 0)
                throw new Exception("班次时间表不能为空");
            var oldPlanShiftTeams = UnitWork.Find<InspectPlanTeam>(u => u.InspectPlanId == planId).OrderBy(u => u.Sort).ToList();
            bool isEqual = true;
            bool needCheckEqual = false;
            if (oldPlanShiftTeams.Any())
            {
                needCheckEqual = true;
                var team = oldPlanShiftTeams.First();
                int columnIndex = 1;
                #region 获取多少班组轮班个数
                if (!string.IsNullOrEmpty(team.Team1))
                {
                    columnIndex = 1;
                }
                if (!string.IsNullOrEmpty(team.Team2))
                {
                    columnIndex = 2;
                }
                if (!string.IsNullOrEmpty(team.Team3))
                {
                    columnIndex = 3;
                }
                if (!string.IsNullOrEmpty(team.Team4))
                {
                    columnIndex = 4;
                }
                if (!string.IsNullOrEmpty(team.Team5))
                {
                    columnIndex = 5;
                }
                if (!string.IsNullOrEmpty(team.Team6))
                {
                    columnIndex = 6;
                }
                if (!string.IsNullOrEmpty(team.Team7))
                {
                    columnIndex = 7;
                }
                if (!string.IsNullOrEmpty(team.Team8))
                {
                    columnIndex = 8;
                }
                if (!string.IsNullOrEmpty(team.Team9))
                {
                    columnIndex = 9;
                }
                if (!string.IsNullOrEmpty(team.Team10))
                {
                    columnIndex = 10;
                }
                #endregion

                if (oldPlanShiftTeams.Count() != shiftTable.Rows.Count || shiftTable.Columns.Count - 1 != columnIndex)
                {
                    isEqual = false;
                    needCheckEqual = false;
                }
            }
            for (var i = 0; i < timeTable.Columns.Count; i++)
            {
                var timeColumn = timeTable.Columns[i];
                var shiftColumn = shiftTable.Columns[i + 1];
                if (timeColumn.ColumnName != shiftColumn.ColumnName)
                    throw new Exception("轮班表和时间表的班次名称不一致");
            }
            UnitWork.Delete<InspectPlanTeamTime>(u => u.InspectPlanId == planId);
            UnitWork.Delete<InspectPlanTeam>(u => u.InspectPlanId == planId);
            //时间表
            for (var i = 0; i < timeTable.Columns.Count; i++)
            {
                string timeString = timeTable.Rows[0][i].ToString().Trim();
                Regex regex = new Regex(@"^(?:[01]\d|2[0-3])(?::[0-5]\d)-(?:[01]\d|2[0-3])(?::[0-5]\d)$");
                if (!regex.IsMatch(timeString))
                {
                    throw new Exception("班次时间设置有误，请检查。");
                }
                UnitWork.Add(new InspectPlanTeamTime()
                {
                    InspectPlanId = planId,
                    Name = timeTable.Columns[i].ColumnName,
                    TimeSpan = timeString,
                    Sort = i
                });
            }
            //轮班表
            var inspectItems = UnitWork.Find<InspectItem>(null).ToList();
            for (var i = 0; i < shiftTable.Rows.Count; i++)
            {
                var team = new InspectPlanTeam() { InspectPlanId = planId, Sort = i };
                for (var j = 1; j < shiftTable.Columns.Count; j++)
                {
                    var itemName = shiftTable.Rows[i][j].ToString().Trim();
                    var obj = inspectItems.Where(u => u.Name == itemName);
                    if (!obj.Any())
                        throw new Exception($"第{i + 1}行，班组：{itemName} 不存在，请检查。");
                    switch (j)
                    {
                        case 1:
                            team.Team1 = obj.First().Id;
                            break;
                        case 2:
                            team.Team2 = obj.First().Id;
                            break;
                        case 3:
                            team.Team3 = obj.First().Id;
                            break;
                        case 4:
                            team.Team4 = obj.First().Id;
                            break;
                        case 5:
                            team.Team5 = obj.First().Id;
                            break;
                        case 6:
                            team.Team6 = obj.First().Id;
                            break;
                        case 7:
                            team.Team7 = obj.First().Id;
                            break;
                        case 8:
                            team.Team8 = obj.First().Id;
                            break;
                        case 9:
                            team.Team9 = obj.First().Id;
                            break;
                        case 10:
                            team.Team10 = obj.First().Id;
                            break;
                    }
                }
                if (needCheckEqual)
                {
                    var oldShiftTeam = oldPlanShiftTeams[i];
                    if (oldShiftTeam.Sort != team.Sort)
                        isEqual = false;
                    if (oldShiftTeam.Team1 != team.Team1)
                        isEqual = false;
                    if (oldShiftTeam.Team2 != team.Team2)
                        isEqual = false;
                    if (oldShiftTeam.Team3 != team.Team3)
                        isEqual = false;
                    if (oldShiftTeam.Team4 != team.Team4)
                        isEqual = false;
                    if (oldShiftTeam.Team5 != team.Team5)
                        isEqual = false;
                    if (oldShiftTeam.Team6 != team.Team6)
                        isEqual = false;
                    if (oldShiftTeam.Team7 != team.Team7)
                        isEqual = false;
                    if (oldShiftTeam.Team8 != team.Team8)
                        isEqual = false;
                    if (oldShiftTeam.Team9 != team.Team9)
                        isEqual = false;
                    if (oldShiftTeam.Team10 != team.Team10)
                        isEqual = false;
                }
                UnitWork.Add(team);
            }
            if (!isEqual)
            {
                UnitWork.Update<InspectPlan>(u => u.Id == planId, u => new InspectPlan() { ShiftNew = 1 });
            }
            UnitWork.Save();
        }

        public InspectShiftTeamTimeResp LoadTeamTime(string planId)
        {
            var items = UnitWork.Find<InspectItem>(null).ToList();
            var teams = UnitWork.Find<InspectPlanTeam>(u => u.InspectPlanId == planId).OrderBy(u => u.Sort).ToList();
            var times = UnitWork.Find<InspectPlanTeamTime>(u => u.InspectPlanId == planId).OrderBy(u => u.Sort).ToList();
            InspectShiftTeamTimeResp resp = new InspectShiftTeamTimeResp { TeamTimes = times };
            foreach (var team in teams)
            {
                for (var i = 0; i < times.Count; i++)
                {
                    switch (i)
                    {
                        case 0:
                            team.Team1 = items.FirstOrDefault(u => u.Id == team.Team1)?.Name;
                            break;
                        case 1:
                            team.Team2 = items.FirstOrDefault(u => u.Id == team.Team2)?.Name;
                            break;
                        case 2:
                            team.Team3 = items.FirstOrDefault(u => u.Id == team.Team3)?.Name;
                            break;
                        case 3:
                            team.Team4 = items.FirstOrDefault(u => u.Id == team.Team4)?.Name;
                            break;
                        case 4:
                            team.Team5 = items.FirstOrDefault(u => u.Id == team.Team5)?.Name;
                            break;
                        case 5:
                            team.Team6 = items.FirstOrDefault(u => u.Id == team.Team6)?.Name;
                            break;
                        case 6:
                            team.Team7 = items.FirstOrDefault(u => u.Id == team.Team7)?.Name;
                            break;
                        case 7:
                            team.Team8 = items.FirstOrDefault(u => u.Id == team.Team8)?.Name;
                            break;
                        case 8:
                            team.Team9 = items.FirstOrDefault(u => u.Id == team.Team9)?.Name;
                            break;
                        case 9:
                            team.Team10 = items.FirstOrDefault(u => u.Id == team.Team10)?.Name;
                            break;
                    }
                }
            }
            resp.Teams = teams;
            return resp;
        }

        public List<InspectPlan> GetShiftPlans()
        {
            return UnitWork.Find<InspectPlan>(u => u.Cycle == 5).ToList();
        }

        public InspectPlanApp(IUnitWork unitWork, IRepository<InspectPlan> repository,
            RevelanceManagerApp app, IAuth auth, IHostingEnvironment hostingEnvironment,
            ILogger<InspectPlanApp> logger)
            : base(unitWork, repository)
        {
            _revelanceApp = app;
            _auth = auth;
            _hostingEnvironment = hostingEnvironment;
            _logger = logger;
        }
    }
}